package com.android.wnba.util.http;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import javax.net.ssl.SSLHandshakeException;

import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpVersion;
import org.apache.http.NoHttpResponseException;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthState;
import org.apache.http.auth.Credentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.text.TextUtils;

import com.android.wnba.util.Util;

public class MyHttpClient {

	protected AuthScope mAuthScope;
	protected BasicHttpContext localcontext;
    
    protected static final int CONNECTION_TIMEOUT_MS = 30 * 1000;
    protected static final int SOCKET_TIMEOUT_MS = 30 * 1000;

    protected static final int RETRIEVE_LIMIT = 20;
    protected static final int RETRIED_TIME = 3;
    
    private static final String CHINAUNICOMWAP = "uniwap";
	private static final String CHINAUNICOM3GNET = "3gwap";
    
    protected Context ctx;

    public MyHttpClient(Context ctx) {
    	this.ctx = ctx;
    }
    
    public DefaultHttpClient create(){
    	HttpParams params = new BasicHttpParams();
        ConnManagerParams.setMaxTotalConnections(params, 10);
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        SchemeRegistry schemeRegistry = new SchemeRegistry();
        schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));

        // Create an HttpClient with the ThreadSafeClientConnManager.
        ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
        DefaultHttpClient client = new DefaultHttpClient(cm, params);
        
        // first request interceptor
        client.addRequestInterceptor(preemptiveAuth, 0);
        
        return client;
    }

    /**
     * HttpRequestInterceptor for DefaultHttpClient
     */
    protected HttpRequestInterceptor preemptiveAuth = new HttpRequestInterceptor() {
        

//		@Override
		public void process(HttpRequest request, HttpContext context)
				throws HttpException, IOException {
			AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
		    CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
		    HttpHost targetHost = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
		
		    if (authState.getAuthScheme() == null) {
		        AuthScope authScope = new AuthScope(targetHost.getHostName(), targetHost.getPort());
		        Credentials creds = credsProvider.getCredentials(authScope);
		        if (creds != null) {
		            authState.setAuthScheme(new BasicScheme());
		            authState.setCredentials(creds);
		        }
		    }
			
		}
    };
    
    /**
     * 异常自动恢复处理, 使用HttpRequestRetryHandler接口实现请求的异常恢复
     */
    protected static HttpRequestRetryHandler requestRetryHandler = new HttpRequestRetryHandler() {
        // 自定义的恢复策略
        public boolean retryRequest(IOException exception, int executionCount,
                HttpContext context) {
            // 设置恢复策略，在发生异常时候将自动重试N次
            if (executionCount >= RETRIED_TIME) {
                // Do not retry if over max retry count
                return false;
            }
            if (exception instanceof NoHttpResponseException) {
                // Retry if the server dropped connection on us
                return true;
            }
            if (exception instanceof SSLHandshakeException) {
                // Do not retry on SSL handshake exception
                return false;
            }
            HttpRequest request = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
            boolean idempotent = (request instanceof HttpEntityEnclosingRequest);
            if (!idempotent) {
                // Retry if the request is considered idempotent
                return true;
            }
            return false;
        }
    };
                    
    protected URI createURI(String url) throws Exception {
        URI uri;
        try {
            uri = new URI(url);
        } catch (URISyntaxException e) {
            throw e;
        }
        return uri;
    }        
    
	/**
	 * 
	 * 判断是否使用移动电话网络
	 * 
	 * @return
	 */
	public static boolean isMobileActive(Context ctx) {
		ConnectivityManager cm = 
			(ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo mobileNet = cm.getActiveNetworkInfo();
		if (mobileNet != null
				&& mobileNet.getType() == ConnectivityManager.TYPE_MOBILE) {
			return true;
		} else {
			return false;
		}
	}
	
	public static HttpURLConnection getURLConnectioin(Context ctx, String surl) throws IOException{
		
		URL url = new URL(Util.Utf8URLencode(surl));
		//HttpURLConnection httpUrl = (HttpURLConnection) url.openConnection();
		Proxy proxy = null;
		if (isMobileActive(ctx)) { // mobile    
			String proxyHost = android.net.Proxy.getDefaultHost();
			int proxyPort = android.net.Proxy.getDefaultPort();
			if (proxyHost != null) 
				proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
		}
		HttpURLConnection rs;
		if (proxy != null) {
			rs = (HttpURLConnection) url.openConnection(proxy);
		} else {
			rs = (HttpURLConnection) url.openConnection();
		}		
		rs.setConnectTimeout(CONNECTION_TIMEOUT_MS);
		rs.setReadTimeout(CONNECTION_TIMEOUT_MS);
		rs.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2) Gecko/20100115 Firefox/3.6");

		return rs;
	}
	
	public static HttpURLConnection getUrlConnecttion(Context context, String surl) throws IOException {
		URL url = new URL(Util.Utf8URLencode(surl));
		HttpURLConnection connection = null;
		if (isMobileNotChinaUniocomWap(context)) {
			String proxyHost = android.net.Proxy.getDefaultHost();
			int proxyPort = android.net.Proxy.getDefaultPort();
			if (!TextUtils.isEmpty(proxyHost)) {
				java.net.Proxy proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP, new InetSocketAddress(proxyHost,
						proxyPort));
				connection = (HttpURLConnection) url.openConnection(proxy);
			}
		}
		if (connection == null)
			connection = (HttpURLConnection) url.openConnection();
		return connection;
	}
	
	public static boolean isMobileNotChinaUniocomWap(Context context) {
		if (null != context) {
			ConnectivityManager connectivityManager = (ConnectivityManager) context
					.getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
			if (null != networkInfo) {
				if (networkInfo.isAvailable() && ConnectivityManager.TYPE_WIFI != networkInfo.getType()) {// 是移动网络
					if (CHINAUNICOMWAP.equals(networkInfo.getExtraInfo())
							|| CHINAUNICOM3GNET.equals(networkInfo.getExtraInfo())) {
						return false;
					} else {
						return true;
					}
				}
			}
		}
		return false;
	}
	
}
